package handlers

import (
	"encoding/json"
	"fmt"
	"goserver/models"
	"goserver/utils"
	"goserver/verify"
	"io"
	"math"
	"net/http"
	"reflect"
	"strconv"

	// 新增：导入验证库
	"go.mongodb.org/mongo-driver/bson"
)

type UserHandler struct {
	*BaseHandler[models.User]
}

func NewUserHandler(repo *models.UserRepository) *UserHandler {
	return &UserHandler{
		BaseHandler: NewBaseHandler(repo.BaseRepository),
	}
}

// 添加用户
func (h *UserHandler) AddUser(w http.ResponseWriter, r *http.Request) {
	var User models.User
	// 先读取请求体并保存
	if r.Method == http.MethodPost {
		err := json.NewDecoder(r.Body).Decode(&User)
		if err != nil {
			utils.Response(w, 201, "JSON解析失败: "+err.Error(), nil) // 响应 Bad Reques
			return
		}
	}

	// 获取当前时间戳
	User.LoginAt = utils.GetCurrentTimestamp()
	User.Status = 1
	User.Role = []string{
		"admin", "user", "guest",
	}

	h.AddEntity(w, r, User, "username")
}

// 删除用户
func (h *UserHandler) DeleteUser(w http.ResponseWriter, r *http.Request) {
	var User models.User
	// 先读取请求体并保存
	if r.Method == http.MethodPost {
		err := json.NewDecoder(r.Body).Decode(&User)
		if err != nil {
			utils.Response(w, http.StatusBadRequest, "JSON解析失败: "+err.Error(), nil) // 响应 Bad Reques
			return
		}
	}
	err := h.DeleteEntity(w, r, User.ID)
	if err != nil {
		utils.Response(w, 201, err.Error(), nil)
		return
	}
	utils.Response(w, 200, "删除成功", nil)

}

func isReflectValueEmpty(fieldVal reflect.Value) bool {
	if !fieldVal.IsValid() {
		return true // 无效值视为“空”
	}

	switch fieldVal.Kind() {
	case reflect.String:
		return fieldVal.String() == ""
	case reflect.Bool:
		return !fieldVal.Bool() // false 视为“空”
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return fieldVal.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return fieldVal.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return fieldVal.Float() == 0
	case reflect.Ptr, reflect.Interface:
		return fieldVal.IsNil()
	case reflect.Slice, reflect.Map, reflect.Array:
		return fieldVal.Len() == 0
	case reflect.Struct:
		// 对结构体可以递归判断所有字段是否都为空
		for i := 0; i < fieldVal.NumField(); i++ {
			if !isReflectValueEmpty(fieldVal.Field(i)) {
				return false
			}
		}
		return true
	default:
		return false // 其他类型暂不认为是“空”
	}
}
func getNotNullValue(user any) (bson.M, error) {
	update := bson.M{}
	val := reflect.ValueOf(user)
	typ := val.Type()
	for i := range make([]struct{}, val.NumField()) {
		fieldVal := val.Field(i)
		fieldTyp := typ.Field(i)
		// 跳过 ID 字段（ID 是更新条件，不是更新内容）
		if fieldTyp.Name == "ID" {
			continue
		}
		if isReflectValueEmpty(fieldVal) {
			continue
		}
		// 获取 bson 标签作为数据库字段名（例如 `bson:"username"`）
		bsonTag := fieldTyp.Tag.Get("bson")

		if bsonTag == "" || bsonTag == "-" { // 忽略无标签或标记为 - 的字段
			continue
		}
		// 添加到 update（键为 bson 标签值，值为字段实际值）
		update[bsonTag] = fieldVal.Interface()
	}
	if len(update) == 0 {
		return nil, fmt.Errorf("未提供需要更新的有效字段")
	}
	return update, nil
}

// 编辑用户
func (h *UserHandler) UpdateUser(w http.ResponseWriter, r *http.Request) {
	// 1. 通过json.NewDecoder(r.Body).Decode(&req) 将req的内容解析到结构体中。
	defer r.Body.Close()
	var User models.User
	// 读取并解析请求体
	if r.Method == http.MethodPost {
		err := json.NewDecoder(r.Body).Decode(&User)
		if err != nil {
			utils.Response(w, 201, "JSON解析失败: "+err.Error(), nil) // 响应 Bad Reques
			return
		}
	}
	// 具体验证请求逻辑
	if err := verify.ValidateStruct(User, "Username", "Password"); err != nil {
		utils.Response(w, 201, "验证失败: "+err.Error(), nil)
	}

	data, err := getNotNullValue(User)
	if err != nil {
		utils.Response(w, 201, "验证失败: "+err.Error(), nil)
		return
	}

	// 调用 BaseRepository 的 Update 方法（仅更新非零值字段）
	uerr := h.BaseHandler.collection.Update(User.ID, data)
	if uerr != nil {
		utils.Response(w, 201, "更新用户失败: "+uerr.Error(), nil)
		return
	}
	utils.Response(w, 200, "编辑成功", nil)
}

// 获取用户列表
func (h *UserHandler) GetUserList(w http.ResponseWriter, r *http.Request) {
	var (
		page     int64 = 1
		pageSize int64 = 10
	)
	var queryParams bson.M
	// 解析查询参数（分页）
	// 由于 utils.ParsePaginationParams 未定义，手动实现分页参数解析
	if r.Method == http.MethodGet {
		// 尝试将查询参数 "page" 转换为 int64 类型
		if pageStr := r.URL.Query().Get("page"); pageStr != "" {
			var err error
			page, err = strconv.ParseInt(pageStr, 10, 64)
			if err != nil {
				page = 1
			}
			if page < 1 {
				page = 1
			}
		}
		if pagesizeStr := r.URL.Query().Get("pagesize"); pagesizeStr != "" {
			var err error
			pageSize, err = strconv.ParseInt(pagesizeStr, 10, 64)
			if err != nil {
				// 转换失败，使用默认值 1
				pageSize = 10
			}
		}

		body, err := io.ReadAll(r.Body)
		if err != nil {
			utils.Response(w, http.StatusBadRequest, "读取请求体失败: "+err.Error(), nil)
			return
		}
		defer r.Body.Close()

		// 检查空请求体
		if len(body) == 0 {
			queryParams = bson.M{}
		} else {
			if err := json.Unmarshal(body, &queryParams); err != nil {
				utils.Response(w, http.StatusBadRequest, "JSON解析失败: "+err.Error(), nil)
				return
			}
		}

	}

	// 调用 BaseRepository 的 FindAll 方法（分页查询）
	data, total, err := h.FindListWithPaginationEntity(w, r, queryParams, page, pageSize)
	if err != nil {
		utils.Response(w, 201, "获取用户列表失败: "+err.Error(), nil)
		return
	}

	// 构建响应数据
	response := map[string]any{
		"list":      data,
		"total":     total,
		"page":      page,
		"totalPage": math.Ceil(float64(total) / float64(pageSize)),
	}
	utils.Response(w, 200, "获取用户列表成功", response)
}

// 获取用户信息
func (h *UserHandler) GetUserInfo(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	var User models.User
	// 读取并解析请求体
	if r.Method == http.MethodPost {
		err := json.NewDecoder(r.Body).Decode(&User)
		if err != nil {
			utils.Response(w, 201, err.Error(), nil)
			return
		}
	}

	// 使用用户ID查询用户信息
	user, err := h.FindByIDEntity(w, r, User.ID)
	if err != nil {
		utils.Response(w, 201, "获取用户信息失败: "+err.Error(), nil)
		return
	}
	// 返回用户信息
	utils.Response(w, 200, "获取用户信息成功", user)

}

// 用户登录
func (h *UserHandler) UserLogin(w http.ResponseWriter, r *http.Request) {
	var User models.User

	//如果请求体为空，直接返回错误
	if r.Method == http.MethodPost {
		defer r.Body.Close()
		body, err := io.ReadAll(r.Body)
		if err != nil {
			utils.Response(w, 201, "读取请求体失败: "+err.Error(), nil)
			return
		}

		if len(body) == 0 {
			utils.Response(w, 201, "请求体不能为空", nil)
			return
		}
		if err := json.Unmarshal(body, &User); err != nil {
			utils.Response(w, 201, "JSON解析失败: "+err.Error(), nil)
			return
		}
	}

	if err := verify.ValidateStruct(User); err != nil {
		utils.Response(w, 201, "验证失败: "+err.Error(), nil)
	}

	utils.Response(w, 200, "登录成功", nil)
	// 先读取请求体并保存
	// if r.Method == http.MethodPost {
	// 	err := json.NewDecoder(r.Body).Decode(&User)
	// 	if err != nil {
	// 		utils.Response(w, 201, "JSON解析失败: "+err.Error(), nil) // 响应 Bad Reques
	// 		return
	// 	}
	// }
	// 具体验证请求逻辑
	// if err := verify.ValidateStruct(User, "test"); err != nil {
	// 	utils.Response(w, 201, "验证失败: "+err.Error(), nil)
	// 	return
	// }
	// utils.Response(w, 200, "登录成功", nil)
}
